﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;

namespace SSharp.Core.Reader {
	/// <summary>
	/// Like a CharReader, with an interface that allows unreading characters, and position control (i.e. not only returns an enumerable.
	/// </summary>
	class CharReaderBufferer : IDisposable {
		private readonly CharReader reader;
		private readonly IEnumerator<char> chars;
		private readonly Stack<char> unread;

		public CharReaderBufferer(Stream stream) {
			reader = new CharReader(stream);
			chars = reader.GetChars().GetEnumerator();
			unread = new Stack<char>();
		}

		/// <summary>
		/// Returns the next char, or null at the end of stream.
		/// </summary>
		public char? ReadChar() {
			if (unread.Count > 0) {
				return unread.Pop();
			} else if (chars.MoveNext()) {
				return chars.Current;
			} else {
				return null;
			}
		}

		/// <summary>
		/// Unreads a character.
		/// </summary>
		public void UnreadChar(char c) {
			unread.Push(c);
		}

		public void Dispose() {
			chars.Dispose();
			reader.Dispose();
		}
	}
}
